﻿using System;
using System.Collections.Generic;

using Moe.ECamel.Common.Entities;

namespace Moe.ECamel.Client.Controllers
{
	public abstract class EntityController<TEntity, TList> where TEntity : new()
	{
		public readonly List<TList> List;
		public readonly int ParentEntityId;

		protected EntityController()
		{
			this.List = new List<TList>();
		}
		protected EntityController(int parentEntityId)
			: this()
		{
			this.ParentEntityId = parentEntityId;
		}

		public ECamelError SubmitChanges(TEntity entity, DetailsMode detailsMode)
		{
			switch (detailsMode)
			{
				case DetailsMode.Create: return Create(entity);
				case DetailsMode.Edit:	return Update(entity);
				case DetailsMode.View: throw new NotSupportedException("Submitting changes in view mode is not supported.");
				default: throw new NotSupportedException("Unsupported DetailsMode: " + detailsMode);
			}
		}

		public virtual ECamelError Create(TEntity entity)
		{
			throw new NotSupportedException("Controller " + this.GetType().Name + " does not support create.");
		}

		public virtual ECamelError Update(TEntity entity)
		{
			throw new NotSupportedException("Controller " + this.GetType().Name + " does not support update.");
		}

		public void RefreshList()
		{
			IList<TList> newList = LoadList();
			this.List.Clear();
			this.List.AddRange(newList);
		}
		protected abstract IList<TList> LoadList();

		public virtual TEntity NewEntity()
		{
			return new TEntity();
		}

		public EntityDetailsController<TEntity, TList> NewCreateController()
		{
			return NewCreateController(NewEntity());
		}
		public EntityDetailsController<TEntity, TList> NewCreateController(TEntity entity)
		{
			return new EntityDetailsController<TEntity, TList>(DetailsMode.Create, entity, this);
		}
		public EntityDetailsController<TEntity, TList> NewEditController(TEntity entity)
		{
			return new EntityDetailsController<TEntity, TList>(DetailsMode.Edit, entity, this);
		}

		public EntityDetailsController<TEntity, TList> NewViewController(TEntity entity)
		{
			return new EntityDetailsController<TEntity, TList>(DetailsMode.View, entity, this);
		}
	}

	public abstract class EntityController<TEntity> : EntityController<TEntity, TEntity> where TEntity : new()
	{
		protected EntityController()
			: base()
		{
		}
		protected EntityController(int parentEntityId)
			: base(parentEntityId)
		{
		}

		public new EntityDetailsController<TEntity> NewCreateController()
		{
			return NewCreateController(NewEntity());
		}
		public new EntityDetailsController<TEntity> NewCreateController(TEntity entity)
		{
			return new EntityDetailsController<TEntity>(DetailsMode.Create, entity, this);
		}
		public new EntityDetailsController<TEntity> NewEditController(TEntity entity)
		{
			return new EntityDetailsController<TEntity>(DetailsMode.Edit, entity, this);
		}
		public new EntityDetailsController<TEntity> NewViewController(TEntity entity)
		{
			return new EntityDetailsController<TEntity>(DetailsMode.View, entity, this);
		}
	}
}
